#include "mainwindow.h"
#include "ui_mainwindow.h"

#define PACK_LEN 200

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setWindowIcon(QIcon(":/image/logo.ico"));


    QLabel *version;
    version = new QLabel("v1.0.220103");
    ui->statusBar->addPermanentWidget (version);
    ui->statusBar->showMessage("Disconnect");
    upgradeForm = new UpgradeForm;
    connect(upgradeForm, SIGNAL(serialWriteData(uint8_t *,int)), this ,SLOT(serialWriteData(uint8_t *,int)));
    connect(this, SIGNAL(serialReadMsg(DataPack *)), upgradeForm ,SLOT(serialReadMsg(DataPack *)));
    configForm = new ConfigForm;
    connect(configForm, SIGNAL(serialWriteData(uint8_t *,int)), this ,SLOT(serialWriteData(uint8_t *,int)));
    connect(this, SIGNAL(serialReadMsg(DataPack *)), configForm ,SLOT(serialReadMsg(DataPack *)));


    serialport = new Serialport;
    connect(serialport, SIGNAL(getData(char *,qint64)), this ,SLOT(serialReadData(char *,qint64)));
    connect(serialport, SIGNAL(connectErr(QString)), this ,SLOT(serialConnectErr(QString)));
    checkPortTimer = new QTimer;
    checkPortTimer->start(500);
    connect(checkPortTimer,SIGNAL(timeout()),this,SLOT(on_reFlash_pressed()));

    connectPortTimer = new QTimer;
    connect(connectPortTimer,SIGNAL(timeout()),this,SLOT(connectTimerCallBack()));

    msgParse = new MsgParse(this);
    dataPack = new DataPack(this);
    connect(msgParse,SIGNAL(parsingOk(uint8_t,uint16_t,QList<uint8_t>,uint8_t,uint8_t)),dataPack,SLOT(parsingOk(uint8_t,uint16_t,QList<uint8_t>,uint8_t,uint8_t)));

    // 限制输入数值 -360 ~ 360
    QRegExp rx("^-?([0-9][0-9]?[0-9]?)$");
    QRegExpValidator *pReg = new QRegExpValidator(rx,this);
    ui->offsetEdit->setValidator(pReg);
}
void MainWindow::serialConnectErr(QString e)
{
    connectPortTimer->stop();
    ui->openPort->setEnabled(true);
    ui->statusBar->showMessage("Connect error!");
    // QMessageBox::about(NULL,"串口被占用", e);
}

MainWindow::~MainWindow()
{
    delete ui;
}

//键盘按下事件
void MainWindow::keyPressEvent(QKeyEvent * event)
{
    static bool ratioEnable = false;
    switch (event->key())
    {
        case Qt::Key_Return: //回车键

        break;
        case Qt::Key_Enter: //小键盘Enter

        break;
        default:break;
    }

    //先检测Ctrl键组合键（Ctrl+F7）（Ctrl+F8）
    if(event->modifiers() == Qt::ControlModifier)
    {
        if(event->key() == Qt::Key_F6)
        {
            ratioEnable = !ratioEnable;
            ui->ratioEdit->setEnabled(ratioEnable);
        }
        else if(event->key() == Qt::Key_F7)
        {
            upgradeForm->show();
        }
        else if(event->key() == Qt::Key_F8)
        {
            configForm->show();
        }

    }
}

//键盘释放事件
void MainWindow::keyReleaseEvent(QKeyEvent *event)
{
}

void MainWindow::serialWriteData(uint8_t *data,int len)
{
   serialport->writeData(data, len);
}

void MainWindow::serialWriteMsg(DataPack *data)
{
    serialWriteData(data->getArrayData(), data->getArrayDataLen());
}
void MainWindow::serialReadData(char *data,qint64 len)
{
    for (int i=0;i<len;i++) {
        uint8_t re = msgParse->parsing((uint8_t)data[i]);
        if(re==1)   // 放在循环里面，防止两帧在一起时漏帧
        {
            if(ui->openPort->text()=="Open")  // 如果收到消息直接打开
            {
                connectPortTimer->stop();
                ui->openPort->setEnabled(true);
                ui->openPort->setText("Close");
                ui->statusBar->showMessage("Connected:"+QString::number(serialBaudList[serialBaudIndex]));
                ui->baudList->setCurrentIndex(serialBaudIndex);
            }
            qDebug()<<"解析成功"<<dataPack->package.type;
            switch(dataPack->package.type)
            {
                case MSG_PORT_CONFIRM:{// 1 端口确认
                    }break;
                case MSG_VERSION_REQ:{  // 版本信息
                    emit serialReadMsg(dataPack);
                }break;
                case MSG_FIRMWARE_REQ:{  // 获得固件请求信息，返回固件内容呢内容
                        emit serialReadMsg(dataPack);
                    }break;
                case MSG_PARAM_SET:{  // 获得固件请求信息，返回固件内容
                          ui->baudList->setCurrentIndex(dataPack->package.payload[0]);

                          ui->offsetEdit->setText(QString::number((int16_t)((int16_t)dataPack->package.payload[1])<<8 | (int8_t)dataPack->package.payload[2]));

                          if(dataPack->package.payload[3]>>2 &0x01)   ui->hdmBox->setCheckState(Qt::CheckState::Checked);
                          else                                        ui->hdmBox->setCheckState(Qt::CheckState::Unchecked);
                          if(dataPack->package.payload[3]>>1 &0x01)   ui->hdgBox->setCheckState(Qt::CheckState::Checked);
                          else                                        ui->hdgBox->setCheckState(Qt::CheckState::Unchecked);
                          if(dataPack->package.payload[3] &0x01)      ui->wmvBox->setCheckState(Qt::CheckState::Checked);
                          else                                        ui->wmvBox->setCheckState(Qt::CheckState::Unchecked);
                          float tempR;
                          uint8_t buf[4];
                          buf[0]=dataPack->package.payload[4];
                          buf[1]=dataPack->package.payload[5];
                          buf[2]=dataPack->package.payload[6];
                          buf[3]=dataPack->package.payload[7];
                          memcpy(&tempR, buf, 4);
                          ui->ratioEdit->setText(QString::number(tempR));
                      }break;
                case MSG_MAG_RAW:{  // 磁力计原始数据
                    emit serialReadMsg(dataPack);
                }break;
                case MSG_MAG_FILTER:{  // 磁力计原始数据
                    emit serialReadMsg(dataPack);
                }break;

                case MSG_WIND_CALIBRATION:{  // 磁力计原始数据
                    emit serialReadMsg(dataPack);
                }break;
                case MSG_MAG_CALIBRATION:{  // 校准
                    emit serialReadMsg(dataPack);
                }break;
                case MSG_VERSION_REPLY:{  // 版本信息
                    emit serialReadMsg(dataPack);
                }break;
                case MSG_UPDATE_FINISH:{  // 更新完成
                    qDebug()<<"更新完成";
                    emit serialReadMsg(dataPack);
                }break;
                case MSG_UPDATE_ERROR:{  // 更新错误
                    qDebug()<<"更新错误";
                    ui->statusBar->showMessage("Firmware missing, please refresh firmware!");
                    upgradeForm->init();
                }break;
                default:break;
            }
        }
    }
}

void MainWindow::on_reFlash_pressed()
{
    static QStringList oldPortStringList;
    QStringList newPortStringList;
    const auto infos = QSerialPortInfo::availablePorts();
    for (const QSerialPortInfo &info : infos)
    {
        newPortStringList += info.portName();
    }
    //更新串口号
    if(newPortStringList.size() != oldPortStringList.size())
    {
        oldPortStringList = newPortStringList;
        ui->portList->clear();
        ui->portList->addItems(serialport->getPortList());
    }
}

void MainWindow::on_openPort_pressed()
{
    if(ui->openPort->text()=="Open"){
        // 开启定时器等待下位机应答，超时后查询下一个波特率
        serialBaudIndex = 0;
        serialport->close();
        serialport->start(ui->portList->currentText(), serialBaudList[serialBaudIndex]);
        ui->openPort->setEnabled(false);
        msgParse->setIdel();
        serialWriteData(portConnectData, sizeof(portConnectData));
        connectPortTimer->start(500);
        ui->statusBar->showMessage("Connect...");
    }else{
        serialport->close();
        ui->statusBar->showMessage("Disconnect");
        ui->openPort->setText("Open");
    }

}

void MainWindow::connectTimerCallBack(void)
{
    serialBaudIndex++;
    if(serialBaudIndex>3){// 没有收到握手回应，表示没接好线
        ui->statusBar->showMessage("Connect error!");
        serialBaudIndex = 0;
        connectPortTimer->stop();
        serialport->close();
        ui->openPort->setText("Open");
        ui->openPort->setEnabled(true);
    }
    else{
        serialport->close();
        msgParse->setIdel();
        serialport->start(ui->portList->currentText(), serialBaudList[serialBaudIndex]);
        serialWriteData(portConnectData, sizeof(portConnectData));
    }
}


// 读取配置信息
void MainWindow::on_readBtn_clicked()
{
    uint8_t data[5] = {0xFE, MSG_PARAM_GET, 0x00,0x00,MSG_PARAM_GET};
    serialWriteData(data, 5);
}

void MainWindow::Sleep(int msec)
{
    QTime dieTime = QTime::currentTime().addMSecs(msec);
    while( QTime::currentTime() < dieTime )
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}




void MainWindow::on_configBtn_clicked()
{
    uint16_t checkSum=0;
    uint8_t data[13] = {0xFE, MSG_PARAM_SET, 0x08,0,0,0,0,0,0,0,0,0x01};
    int baud = ui->baudList->currentText().toUInt();
    if(baud==4800)  		data[3] = 0;
    else if(baud==9600)  	data[3] = 1;
    else if(baud==38400)  	data[3] = 2;
    else if(baud==115200)   data[3] = 3;

    data[4] = ui->offsetEdit->text().toShort()>>8 & 0x00ff;
    data[5] = ui->offsetEdit->text().toShort() & 0x00ff;
    if(ui->hdmBox->checkState()==Qt::CheckState::Checked)   data[6] = 0x04;
    if(ui->hdgBox->checkState()==Qt::CheckState::Checked)   data[6] = data[6] | 0x02;
    if(ui->wmvBox->checkState()==Qt::CheckState::Checked)   data[6] = data[6] | 0x01;
    float temp = ui->ratioEdit->text().toFloat();
    memcpy(data+7,&temp,4);

    checkSum = data[1]+data[2]+data[3]+data[4]+data[5]+data[6]+data[7]+data[8]+data[9]+data[10];
    data[11]= checkSum>>8 &0x00ff;
    data[12]= checkSum & 0x00ff;
    //qDebug()<<data[3]<<" "<<data[4]<<" "<<data[5];
    serialWriteData(data, sizeof(data));

    Sleep(500);
    on_openPort_pressed();
    on_openPort_pressed();
}
